<template>
  <div class="app-container">
    <el-container class="form-designer">
      <!-- 左侧组件面板 -->
      <el-aside class="panel components-panel">
        <div class="panel-header">
          <i class="el-icon-menu"></i>
          <span>组件库</span>
        </div>
        <div class="panel-content">
          <div class="components-list">
            <div v-for="(comp, index) in components" :key="index" 
                 class="component-item" draggable="true"
                 @dragstart="dragStart($event, comp)">
              <i :class="comp.icon"></i>
              <span>{{ comp.label }}</span>
            </div>
          </div>
        </div>
      </el-aside>
      
      <!-- 中间设计面板 -->
      <el-main class="panel design-panel">
        <div class="panel-header">
          <i class="el-icon-edit"></i>
          <span>设计区域</span>
          <div class="action-buttons">
            <el-button type="primary" size="small" @click="previewForm" plain>
              <i class="el-icon-view"></i> 预览
            </el-button>
            <el-button type="danger" size="small" @click="clearForm" plain>
              <i class="el-icon-delete"></i> 清空
            </el-button>
          </div>
        </div>
        <div class="panel-content">
          <div class="design-area" :class="{empty: formItems.length === 0}"
               @dragover.prevent @drop="dropItem">
            <div v-if="formItems.length === 0" class="empty-tip">
              <i class="el-icon-s-promotion"></i>
              <p>从左侧拖拽组件到此处开始设计表单</p>
            </div>
            
            <div v-else>
              <div class="form-title">表单设计器</div>
              <el-form label-width="100px" size="medium">
                <draggable 
                  v-model="formItems" 
                  group="formItems" 
                  item-key="id"
                  @start="drag=true" 
                  @end="drag=false">
                  <template #item="{element, index}">
                    <div class="form-item" :class="{selected: currentItem && currentItem.id === element.id}"
                         @click="selectItem(element)">
                      <div class="form-item-header">
                        <span class="form-item-label">
                          <i :class="getIcon(element.type)"></i>
                          {{ element.label || element.type }}
                        </span>
                        <div class="form-item-actions">
                          <el-button size="mini" type="danger" icon="el-icon-delete" circle 
                                    @click.stop="removeItem(index)"></el-button>
                        </div>
                      </div>
                      <div class="form-preview">
                        <component-preview :item="element" :preview="false"></component-preview>
                      </div>
                    </div>
                  </template>
                </draggable>
              </el-form>
            </div>
          </div>
        </div>
      </el-main>
      
      <!-- 右侧属性面板 -->
      <el-aside class="panel properties-panel">
        <div class="panel-header">
          <i class="el-icon-setting"></i>
          <span>属性设置</span>
        </div>
        <div class="panel-content" v-if="currentItem">
          <el-form class="properties-form" label-width="80px" size="medium">
            <el-form-item label="字段名">
              <el-input v-model="currentItem.model" placeholder="请输入字段名"></el-input>
            </el-form-item>
            <el-form-item label="标签">
              <el-input v-model="currentItem.label" placeholder="请输入标签"></el-input>
            </el-form-item>
            <el-form-item label="提示文字">
              <el-input v-model="currentItem.placeholder" placeholder="请输入提示文字"></el-input>
            </el-form-item>
            
            <template v-if="currentItem.type === 'select' || currentItem.type === 'radio' || currentItem.type === 'checkbox'">
              <el-form-item label="选项">
                <el-button type="primary" size="mini" @click="addOption">添加选项</el-button>
              </el-form-item>
              <div v-for="(option, idx) in currentItem.options" :key="idx" class="option-item">
                <el-input v-model="option.label" placeholder="标签" style="width: 45%; margin-right: 10px;"></el-input>
                <el-input v-model="option.value" placeholder="值" style="width: 45%;"></el-input>
                <el-button type="danger" icon="el-icon-delete" circle size="mini" 
                          @click="removeOption(idx)"></el-button>
              </div>
            </template>
            
            <el-form-item label="是否必填">
              <el-switch v-model="currentItem.required"></el-switch>
            </el-form-item>
            
            <el-form-item label="尺寸">
              <el-radio-group v-model="currentItem.size">
                <el-radio-button label="medium">中等</el-radio-button>
                <el-radio-button label="small">较小</el-radio-button>
                <el-radio-button label="mini">迷你</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-form>
        </div>
        <div v-else class="panel-content empty-tip">
          <i class="el-icon-s-marketing"></i>
          <p>请选择要配置的表单项</p>
        </div>
      </el-aside>
    </el-container>
    
    <!-- 预览对话框 -->
    <el-dialog title="表单预览" v-model="previewVisible" width="50%" top="5vh">
      <el-form :model="previewFormModel" label-width="100px" size="medium">
        <template v-for="(item, index) in formItems" :key="index">
          <el-form-item :label="item.label" :prop="item.model" 
                       :rules="item.required ? [{ required: true, message: '该字段为必填项' }] : []">
            <component-preview :item="item" :preview="true" v-model="previewFormModel[item.model]"></component-preview>
          </el-form-item>
        </template>
      </el-form>
      <template #footer>
        <el-button @click="previewVisible = false">关闭</el-button>
        <el-button type="primary" @click="submitPreviewForm">提交</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { ref, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';

// 组件预览实现 - 使用标准模板语法
const ComponentPreview = {
  template: `
    <div>
      <!-- 输入框 -->
      <el-input
        v-if="item.type === 'input'"
        v-model="value"
        :placeholder="item.placeholder"
        :size="item.size"
        :disabled="!preview"
      ></el-input>
      
      <!-- 文本域 -->
      <el-input
        v-else-if="item.type === 'textarea'"
        type="textarea"
        v-model="value"
        :placeholder="item.placeholder"
        :rows="4"
        :size="item.size"
        :disabled="!preview"
      ></el-input>
      
      <!-- 下拉选择 -->
      <el-select
        v-else-if="item.type === 'select'"
        v-model="value"
        :placeholder="item.placeholder"
        :size="item.size"
        style="width: 100%"
        :disabled="!preview"
      >
        <el-option
          v-for="option in item.options"
          :key="option.value"
          :label="option.label"
          :value="option.value"
        ></el-option>
      </el-select>
      
      <!-- 单选框 -->
      <el-radio-group
        v-else-if="item.type === 'radio'"
        v-model="value"
        :size="item.size"
        :disabled="!preview"
      >
        <el-radio
          v-for="option in item.options"
          :key="option.value"
          :label="option.value"
        >
          {{ option.label }}
        </el-radio>
      </el-radio-group>
      
      <!-- 复选框 -->
      <el-checkbox-group
        v-else-if="item.type === 'checkbox'"
        v-model="value"
        :size="item.size"
        :disabled="!preview"
      >
        <el-checkbox
          v-for="option in item.options"
          :key="option.value"
          :label="option.value"
        >
          {{ option.label }}
        </el-checkbox>
      </el-checkbox-group>
      
      <!-- 日期选择 -->
      <el-date-picker
        v-else-if="item.type === 'date'"
        v-model="value"
        type="date"
        :placeholder="item.placeholder"
        :size="item.size"
        style="width: 100%"
        :disabled="!preview"
      ></el-date-picker>
      
      <!-- 未知组件 -->
      <div v-else>未知组件类型</div>
    </div>
  `,
  props: {
    item: Object,
    preview: {
      type: Boolean,
      default: false
    },
    modelValue: [String, Number, Array, Date]
  },
  emits: ['update:modelValue'],
  computed: {
    value: {
      get() {
        return this.modelValue;
      },
      set(value) {
        this.$emit('update:modelValue', value);
      }
    }
  }
};

export default {
  components: {
    ComponentPreview
  },
  setup() {
    // 可用的组件列表
    const components = ref([
      { type: 'input', label: '输入框', icon: 'el-icon-edit' },
      { type: 'select', label: '下拉框', icon: 'el-icon-s-unfold' },
      { type: 'radio', label: '单选框', icon: 'el-icon-circle-check' },
      { type: 'checkbox', label: '多选框', icon: 'el-icon-check' },
      { type: 'date', label: '日期选择', icon: 'el-icon-date' },
      { type: 'textarea', label: '文本域', icon: 'el-icon-document' }
    ]);
    
    // 表单设计项
    const formItems = ref([]);
    
    // 当前选中的表单项
    const currentItem = ref(null);
    
    // 预览对话框可见性
    const previewVisible = ref(false);
    
    // 预览表单数据模型
    const previewFormModel = ref({});
    
    // 获取组件图标
    const getIcon = (type) => {
      const comp = components.value.find(c => c.type === type);
      return comp ? comp.icon : 'el-icon-question';
    };
    
    // 拖拽开始
    const dragStart = (event, comp) => {
      event.dataTransfer.setData('component', JSON.stringify(comp));
    };
    
    // 放置组件到设计区域
    const dropItem = (event) => {
      event.preventDefault();
      const compData = JSON.parse(event.dataTransfer.getData('component'));
      const newItem = {
        id: `form-item-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
        type: compData.type,
        label: compData.label,
        model: `field_${formItems.value.length + 1}`,
        placeholder: '请输入' + compData.label,
        required: false,
        size: 'medium',
        value: null
      };
      
      // 为选择类组件添加选项
      if (['select', 'radio', 'checkbox'].includes(compData.type)) {
        newItem.options = [
          { label: '选项1', value: '1' },
          { label: '选项2', value: '2' }
        ];
      }
      
      formItems.value.push(newItem);
    };
    
    // 选择表单项
    const selectItem = (item) => {
      currentItem.value = item;
    };
    
    // 删除表单项
    const removeItem = (index) => {
      if (currentItem.value === formItems.value[index]) {
        currentItem.value = null;
      }
      formItems.value.splice(index, 1);
    };
    
    // 添加选项
    const addOption = () => {
      if (currentItem.value && currentItem.value.options) {
        currentItem.value.options.push({
          label: '新选项',
          value: 'value' + (currentItem.value.options.length + 1)
        });
      }
    };
    
    // 删除选项
    const removeOption = (index) => {
      if (currentItem.value && currentItem.value.options) {
        currentItem.value.options.splice(index, 1);
      }
    };
    
    // 预览表单
    const previewForm = () => {
      // 初始化预览数据模型
      previewFormModel.value = {};
      formItems.value.forEach(item => {
        previewFormModel.value[item.model] = null;
      });
      previewVisible.value = true;
    };
    
    // 清空表单
    const clearForm = () => {
      ElMessageBox.confirm('确定要清空所有表单项吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        formItems.value = [];
        currentItem.value = null;
        ElMessage.success('已清空所有表单项');
      }).catch(() => {});
    };
    
    // 提交预览表单
    const submitPreviewForm = () => {
      ElMessage.success('表单提交成功！');
      previewVisible.value = false;
    };
    
    return {
      components,
      formItems,
      currentItem,
      previewVisible,
      previewFormModel,
      getIcon,
      dragStart,
      dropItem,
      selectItem,
      removeItem,
      addOption,
      removeOption,
      previewForm,
      clearForm,
      submitPreviewForm
    };
  }
};
</script>

<style lang="scss" scoped>
.app-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 20px;
  background: #f0f2f5;
}

.form-designer {
  display: flex;
  flex: 1;
  gap: 16px;
  background: white;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}

.panel {
  background: white;
  border-radius: 0px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border: 1px solid #ebeef5;
}

.panel-header {
  padding: 16px;
  font-size: 16px;
  font-weight: bold;
  background: linear-gradient(90deg, #f0f7ff, #f8f8f8);
  border-bottom: 1px solid #ebeef5;
  display: flex;
  align-items: center;
  gap: 8px;
  
  .action-buttons {
    margin-left: auto;
  }
}

.panel-content {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
  background: #fafafa;
}

.components-panel {
  width: 260px;
  flex-shrink: 0;
}

.design-panel {
  flex: 1;
}

.properties-panel {
  width: 320px;
  flex-shrink: 0;
}

.components-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.component-item {
  border: 1px dashed #dcdfe6;
  border-radius: 8px;
  padding: 16px 8px;
  cursor: move;
  text-align: center;
  transition: all 0.3s;
  background: white;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03);
  
  i {
    font-size: 24px;
    margin-bottom: 10px;
    display: block;
    color: #606266;
  }
  
  &:hover {
    border-color: #409eff;
    color: #409eff;
    background: #ecf5ff;
    transform: translateY(-3px);
    box-shadow: 0 4px 10px rgba(64, 158, 255, 0.15);
    
    i {
      color: #409eff;
    }
  }
}

.design-area {
  min-height: 100%;
  border: 2px dashed #dcdfe6;
  border-radius: 8px;
  padding: 25px;
  background: #fafafa;
  transition: all 0.3s;
  
  &.empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #c0c4cc;
    background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="%23fafafa"/><path d="M20,50 L80,50 M50,20 L50,80" stroke="%23dcdfe6" stroke-width="2" stroke-dasharray="5,5"/></svg>');
    background-size: 100px 100px;
  }
  
  &:hover {
    border-color: #a0cfff;
  }
}

.empty-tip {
  text-align: center;
  padding: 40px 20px;
  color: #909399;
  
  i {
    font-size: 48px;
    margin-bottom: 16px;
    display: block;
    color: #c0c4cc;
  }
  
  p {
    font-size: 16px;
    color: #909399;
  }
}

.form-item {
  padding: 16px;
  border: 1px solid transparent;
  border-radius: 8px;
  margin-bottom: 20px;
  position: relative;
  cursor: move;
  background: white;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
  transition: all 0.3s;
  
  &:hover {
    border-color: #dcdfe6;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
  }
  
  &.selected {
    border: 2px solid #409eff;
    background-color: #f0f7ff;
    box-shadow: 0 5px 15px rgba(64, 158, 255, 0.2);
  }
}

.form-item-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px dashed #ebeef5;
}

.form-item-label {
  font-weight: bold;
  font-size: 15px;
  color: #409eff;
  display: flex;
  align-items: center;
  gap: 8px;
}

.form-item-actions {
  opacity: 0;
  transition: opacity 0.3s;
}

.form-item:hover .form-item-actions {
  opacity: 1;
}

.form-item-actions button {
  padding: 2px;
  margin-left: 4px;
}

.form-preview {
  padding: 12px;
}

.properties-form .el-form-item {
  margin-bottom: 18px;
}

.form-title {
  text-align: center;
  margin-bottom: 24px;
  color: #409eff;
  font-size: 20px;
  font-weight: bold;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.option-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  gap: 8px;
}

:deep(.el-dialog) {
  border-radius: 12px;
  overflow: hidden;
  
  .el-dialog__header {
    background: linear-gradient(90deg, #f0f7ff, #f8f8f8);
    padding: 16px 20px;
    margin: 0;
    border-bottom: 1px solid #ebeef5;
  }
  
  .el-dialog__body {
    padding: 30px;
    max-height: 70vh;
    overflow-y: auto;
  }
}
</style>